<?php

/*
 * This file is part of the yuki package.
 * Copyright (c) 2011 olamedia <olamedia@gmail.com>
 *
 * This source code is release under the MIT License.
 * 
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 * yCallable represents a PHP callable.
 * 
 * @package yuki
 * @subpackage callable
 * @author olamedia
 * @license http://www.opensource.org/licenses/mit-license.php MIT
 * @version SVN: $Id: yCallable.php 109 2011-02-19 08:11:02Z olamedia@gmail.com $
 */
class yCallable{
    protected $_callable = null;
    /**
     * Classes & objects without __invoke will accept first argument as method to call
     * @var boolean
     */
    protected $_method = true;
    /**
     * Constructor.
     * @param mixed $callable A valid PHP callable or string in format class/method
     */
    public function __construct($callable){
        if (is_string($callable)){
            if (($p = strpos($callable, '/')) !== false){
                $this->_callable = explode('/', $callable);
            }else{
                $this->_callable = $callable;
                $this->_method = false;
            }
        }elseif (is_array($callable)){
            $this->callable = $callable;
        }elseif (is_object($callable)){
            $this->_callable = $callable;
            if (!is_callable($callable)){
                $this->_method = false;
            }
        }
        // FIXME: throw yException here
    }
    /**
     * Calls the current callable with the given arguments.
     */
    public function call(){
        $arguments = func_get_args();
        if ($this->_method){
            return call_user_func_array($this->_callable, $arguments);
        }else{
            if (count($arguments)){
                $method = (string) array_shift($arguments);
                return call_user_func_array(
                        array($this->_callable, $method), $arguments
                );
            }
            // FIXME: can't call
        }
    }
}

